package com.icesoft.core.common.helper.lock.base;

import java.util.function.Supplier;

public interface ICacheLock {

	/**
	 * 针对相同的key，同一时刻只运行一次，其他线程跳过runnable，不等待直接继续执行
	 */
	default boolean runIfLocked(String key, Runnable runnable) {
		return runIfLocked(key, runnable, false);
	}

	/**
	 * 针对相同的key，同一时刻只运行一次，其他线程不执行
	 * 
	 * @param isWait
	 *            是否等待其他线程正在运行的runnable执行完成，默认最大等待时间3s
	 * @return 是否运行了
	 */
	default boolean runIfLocked(String key, Runnable runnable, boolean isWait) {
		return runIfLocked(key, runnable, isWait, 3);
	}

	/**
	 * 针对相同的key，同一时刻只运行一次，其他线程不执行
	 * 
	 * @param isWait
	 *            是否等待其他线程正在运行的runnable执行完成
	 * @param waitSeconds
	 *            isWait为true时生效，表示其他线程等待的最大超时时间
	 * @return 是否运行了
	 */
	boolean runIfLocked(String key, Runnable runnable, boolean isWait, int waitSeconds);

	/**
	 * loadCallable返回null，执行createCallable后返回loadCallable值
	 * 
	 * @param loadCallable
	 *            if return null , call createCallable
	 * @return loadCallable
	 */
	default <R> R loadOrCreateIfNull(String key, Supplier<R> loadCallable, Supplier<R> createCallable) {
		R model = loadCallable.get();
		if (model == null) {
			runIfLocked(key, () -> {
				if (loadCallable.get() == null) {
					createCallable.get();
				}
			}, true);
			model = loadCallable.get();
		}
		return model;
	}
}
